﻿$import( "SmitearWebGL.Objects.Canvas.ScreenQuad" );
$import( "SmitearWebGL.Programs.LightPrePass.HBlurProgram" );
$import( "SmitearWebGL.Programs.LightPrePass.VBlurProgram" );

SmitearWebGL.Objects.Canvas.LightPrePass.Blur = SmitearWebGL.Objects.Canvas.ScreenQuad.extend(
{
	init : function()
	{
		this._super();
		this._registClass( "SmitearWebGL.Objects.Canvas.LightPrePass.Blur" );
		
		this.gaussMultiplier = -1.0;
		this.gaussMean = -1.0;
		this.gaussStdDev = -1.0;
	}
	,
	_computeGaussianValue : function( x, mean, std_deviation )
	{
		return ( 1.0 / Math.sqrt( 2.0 * Math.PI * std_deviation * std_deviation ) )
		* Math.exp( ( -( ( x - mean ) * ( x - mean ) ) ) / ( 2.0 * std_deviation * std_deviation ) );
	}
}
);

SmitearWebGL.Objects.Canvas.LightPrePass.Blur.GaussMultiplier = 0.25;
SmitearWebGL.Objects.Canvas.LightPrePass.Blur.GaussMean = 0.0;
SmitearWebGL.Objects.Canvas.LightPrePass.Blur.GaussStdDev = 0.15;

SmitearWebGL.Objects.Canvas.LightPrePass.HBlur = SmitearWebGL.Objects.Canvas.LightPrePass.Blur.extend(
{
	/******** constructor ********/

	init : function()
	{
		this._super();
		this._registClass( "SmitearWebGL.Objects.Canvas.LightPrePass.HBlur" );

		this._hBlurTech = null;

		this._hBloomOffsets = null;
		this._hBloomWeights = null;
	}
	,
	calculateOffsets : function()
	{
		if ( this.gaussMultiplier != SmitearWebGL.Objects.Canvas.LightPrePass.Blur.GaussMultiplier ||
			this.gaussMean != SmitearWebGL.Objects.Canvas.LightPrePass.Blur.GaussMean ||
			this.gaussStdDev != SmitearWebGL.Objects.Canvas.LightPrePass.Blur.GaussStdDev )
		{
			var srcTex = this.getTextureAt( 0 );
	
			var sU = 1.0 / srcTex.getWidth();
			var sV = 1.0 / srcTex.getHeight();
	
			this._hBloomOffsets = new Float32Array(9);
			this._hBloomWeights = new Float32Array(9);
			
			this.gaussMultiplier = SmitearWebGL.Objects.Canvas.LightPrePass.Blur.GaussMultiplier;
			this.gaussMean = SmitearWebGL.Objects.Canvas.LightPrePass.Blur.GaussMean;
			this.gaussStdDev = SmitearWebGL.Objects.Canvas.LightPrePass.Blur.GaussStdDev;
	
			for( var i = 0; i < 9; i++ )
			{
				this._hBloomOffsets[i] = ( i - 4.0 ) * ( 1.0 / srcTex.getWidth() );
				var x = ( i - 4.0 ) / 4.0;
				this._hBloomWeights[i] = this.gaussMultiplier * this._computeGaussianValue( x, this.gaussMean, this.gaussStdDev );
			}
		}
	}
	,

	//override render function
	renderCallBack : function()
	{
		this.calculateOffsets();
		
		var program = this._hBlurTech;
		
		var hr = SmitearWebGL.Core.HResult.SUCCESS;

		hr |= program.activeShader();
		hr |= program.activeUniform( this );
		
		hr |= this._vertexBuffer.bind();
		hr |= this._vertexBuffer.active( program.getShader() );

		this.context.gl.drawArrays( this.context.gl.TRIANGLE_STRIP, 0, 4 );
		
		return hr;
	}
	,
	_createResource : function( params )
	{
		this._super();

		this._hBlurTech = this.context.programManager.getResourceByName( SmitearWebGL.Programs.InternalPrograms.Type.LP_HBLUR );

		this._hBloomOffsets = null;
		this._hBloomWeights = null;
	}
	,
	_destroyResource : function()
	{
		this._super();
		
		this._hBlurTech = null;
		this._hBloomOffsets = null;
		this._hBloomWeights = null;
	}
}
);

SmitearWebGL.Objects.Canvas.LightPrePass.VBlur = SmitearWebGL.Objects.Canvas.LightPrePass.Blur.extend(
{
	/******** constructor ********/

	init : function()
	{
		this._super();
		this._registClass( "SmitearWebGL.Objects.Canvas.LightPrePass.VBlur" );

		this._vBlurTech = null;

		this._vBloomOffsets = null;
		this._vBloomWeights = null;
	}
	,
	calculateOffsets : function()
	{
		if ( this.gaussMultiplier != SmitearWebGL.Objects.Canvas.LightPrePass.Blur.GaussMultiplier ||
			this.gaussMean != SmitearWebGL.Objects.Canvas.LightPrePass.Blur.GaussMean ||
			this.gaussStdDev != SmitearWebGL.Objects.Canvas.LightPrePass.Blur.GaussStdDev )
		{
			var srcTex = this.getTextureAt( 0 );
	
			if ( ! srcTex ) return;
	
			var sU = 1.0 / srcTex.getWidth();
			var sV = 1.0 / srcTex.getHeight();
	
			this._vBloomOffsets = new Float32Array(9);
			this._vBloomWeights = new Float32Array(9);
				
			this.gaussMultiplier = SmitearWebGL.Objects.Canvas.LightPrePass.Blur.GaussMultiplier;
			this.gaussMean = SmitearWebGL.Objects.Canvas.LightPrePass.Blur.GaussMean;
			this.gaussStdDev = SmitearWebGL.Objects.Canvas.LightPrePass.Blur.GaussStdDev;
	
			for( var i = 0; i < 9; i++ )
			{
				this._vBloomOffsets[i] = ( i - 4.0 ) * ( 1.0 / srcTex.getHeight() );
				var x = ( i - 4.0 ) / 4.0;
				this._vBloomWeights[i] = this.gaussMultiplier * this._computeGaussianValue( x, this.gaussMean, this.gaussStdDev );
			}
		}
	}
	,

	//override render function
	renderCallBack : function()
	{
		this.calculateOffsets();
		
		var program = this._vBlurTech;
		
		var hr = SmitearWebGL.Core.HResult.SUCCESS;

		hr |= program.activeShader();
		hr |= program.activeUniform( this );
		
		hr |= this._vertexBuffer.bind();
		hr |= this._vertexBuffer.active( program.getShader() );
		
		this.context.gl.drawArrays( this.context.gl.TRIANGLE_STRIP, 0, 4 );
		
		return hr;
	}
	,
	_createResource : function( params )
	{
		this._super();

		this._vBlurTech = this.context.programManager.getResourceByName( SmitearWebGL.Programs.InternalPrograms.Type.LP_VBLUR );

		this._vBloomOffsets = null;
		this._vBloomWeights = null;
	}
	,
	_destroyResource : function()
	{
		this._super();
		
		this._vBlurTech = null;

		this._vBloomOffsets = null;
		this._vBloomWeights = null;
	}
}
);